#region license
# This file is part of Grawlix.
# 
# Grawlix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# 
# Grawlix is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with Grawlix.  If not, see
# <http://www.gnu.org/licenses/>.
#endregion

"""Create standard set of exception constructors."""

namespace Grawlix.Meta
import System
import Boo.Lang.Compiler

transient class ExceptionConstructorsAttribute(AbstractAstAttribute):
"""Implements several standard exception constructors."""
	
	override def Apply(targetNode as Ast.Node):
	"""
	Apply the attribute to the specified node.
	Param targetNode: The node to apply to.
	"""
		if Ast.NodeType.ClassDefinition != targetNode.NodeType:
			InvalidNodeForAttribute('ClassDefinition')
			return
		
		# TODO: Ignore existing constructors,
		# make sure superclass versions exist,
		# suppress serialization if transient.
		
		classDefinition = targetNode as Ast.ClassDefinition
		classDefinition.Members.Add(SpawnDefault())
		classDefinition.Members.Add(SpawnMessage())
		classDefinition.Members.Add(SpawnMessageNested())
#		classDefinition.Members.Add(SpawnNested())
		classDefinition.Members.Add(SpawnSerialization())
	
	protected static def SpawnDefault():
	"""
	Spawn a default constructor.
	Returns: The default constructor.
	"""
		return [|
			def constructor():
			"""Default constructor."""
				super()
		|]
		
	protected static def SpawnMessage():
	"""
	Spawn a message constructor.
	Returns: The message constructor.
	"""
		return [|
			def constructor([required] message as string):
			"""
			Create a new exception.
			Param message: The exception text.
			"""
				super(message)
		|]
		
	protected static def SpawnMessageNested():
	"""
	Spawn a message-nested constructor.
	Returns: The message-nested constructor.
	"""
		return [|
			def constructor([required] message as string,
			                [required] exception as System.Exception):
			"""
			Create a new exception, specifying a base exception.
			Param message: The exception text.
			Param exception: The original exception to base it upon.
			"""
				super(message, exception)
		|]
		
	protected static def SpawnNested():
	"""
	Spawn a nested constructor.
	Returns: The nested constructor.
	"""
		return [|
			def constructor([required] exception as System.Exception):
			"""
			Create a new exception.
			Param exception: The original exception to base it upon.
			"""
				self(exception.Message, exception)
		|]
		
	protected static def SpawnSerialization():
	"""
	Spawn a serialization constructor.
	Returns: The serialization constructor.
	"""
		return [|
			protected def constructor(
				[required] info as
					System.Runtime.Serialization.SerializationInfo,
			    context as System.Runtime.Serialization.StreamingContext):
			"""
			Serialization constructor.
			Param info: The Serialization info for the exception.
			Param context: The StreamingContext of the serialization.
			"""
				super(info, context)
		|]


